package com.huacheng.authorization.controller;

import com.huacheng.authorization.util.CookieUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URI;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/login")
public class LoginController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final String Domain = "activate.navicat.com";

    @PostMapping("/token")
    public String loginToken(@RequestBody Map<String,String> resource) {
        if(resource.get("username") == null || resource.get("password") == null) {
            return "用户名密码不能为空";
        }

        /**从注册中心中获取到授权认证服务器的uri*/
        ServiceInstance serviceInstance = discoveryClient.getInstances("SERVICE-AUTHORIZATION").get(0);
        URI uri = serviceInstance.getUri();
        System.out.println(uri);
        String authUrl = uri + "/oauth/token";
        //编辑请求体信息
        MultiValueMap<String,String> body = new LinkedMultiValueMap<String,String>();
        body.add("client_id","c1");
        body.add("client_secret","secret");
        body.add("grant_type","password");
        body.add("username",resource.get("username"));
        body.add("password",resource.get("password"));

        /**设置请求参数*/
        HttpEntity<MultiValueMap<String, String>> multiValueMapHttpEntity = new HttpEntity<MultiValueMap<String, String>>(body,null);
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                //当响应的值为400或401时候也要正常响应，不要抛出异常
                if (response.getRawStatusCode() != 400 && response.getRawStatusCode() != 401) {
                    super.handleError(response);
                }
            }
        });

        /**发送HTTP请求：post类型*/
        ResponseEntity<Map> exchange = restTemplate.exchange(authUrl, HttpMethod.POST,multiValueMapHttpEntity,Map.class);
        Map access = exchange.getBody();
        if(access.get("jti")== null || access.get("access_token") == null || access.get("refresh_token") == null) {
            logger.info("令牌申请失败:username:{},password:{}",resource.get("username"),resource.get("password"));
           throw new RuntimeException("令牌申请失败，账号或密码错误");
        }
        String jti = (String)access.get("jti");
        String access_token = (String)access.get("access_token");
        String refresh_token = (String)access.get("refresh_token");
        stringRedisTemplate.opsForValue().set(jti,access_token,1800, TimeUnit.SECONDS);
        logger.info("jti:" + jti);
        logger.info("jwt长龄牌:" + access_token);
        logger.info("刷新令牌:" + refresh_token);

        /**将短令牌存入到cookie中*/
        //从spring上下文中获取request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = requestAttributes.getResponse();
        CookieUtil.addCookie(response,Domain,"/","jti",jti,1800,true);
        return "登陆成功";
    }
}
